<?php
// +----------------------------------------------------------------------
// | ZengCMS [ 火火 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2018 http://zengcms.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 火火 <zengcms@qq.com>
// +----------------------------------------------------------------------

// +----------------------------------------------------------------------
// | 自定义验证器的基类
// +----------------------------------------------------------------------
namespace app\api\validate;

use think\Validate;
use think\facade\Request;
use app\api\lib\exception\MissException;

class BaseValidate extends Validate
{
    // 异常代码
    public $code = 0;
    // http状态码
    public $httpCode = 400;
    /**
     * 检测所有客户端发来的参数是否符合验证类规则
     * 基类定义了很多自定义验证方法
     * 这些自定义验证方法其实，也可以直接调用
     * @throws MissException
     * @return true
     */
    public function goCheck($data=[])
    {
        // 注意头部必须设置contetn-type:application/json
        $request = Request::instance();
        // param获取当前请求的所有变量(经过过滤)即post和get的参数(不包括headers的参数)及相应值。
        if(!$data){
            $params = $request->param();
        }else{
            $params = $data;
        }
        // 获取header里的signature参数，放入验证参数数组(signature签名)
        $params['signature'] = $request->header('signature');
        // 获取header里的timestamp参数 放入验证参数数组(timestamp时间戳)
        $params['timestamp'] = $request->header('timestamp');
        // 获取header里的nonce参数 放入验证参数数组(nonce随机字符串)
        $params['nonce'] = $request->header('nonce');
        // 获取header里的token参数 放入验证参数数组(token登录令牌)
        $params['token'] = $request->header('token');
        // 检查参数是否符合要求
        if (!$this->check($params)) {
            $exception = new MissException([
                // 异常代码
                'code' => $this->code,
                // 异常消息内容，$this->error有一个问题，并不是一定返回数组，需要判断。
                'message' => is_array($this->error) ? implode(';', $this->error) : $this->error,
                // http状态码
                'httpCode' => $this->httpCode,
            ]);
            throw $exception;
        }
        return true;
    }
    /**
     * 根据验证规则取规定字段及相应值，防止恶意更新非客户端字段
     * @param  [array] $arrays [通常传入request.post变量数组]
     * @return [array]         [按照规则key过滤后的变量数组]
     * @throws MissException
     */
    public function getDataByRule($arrays)
    {
        // 暂时不用这样报错，过滤就可以了，后续业务需要再考虑。
        /* if (array_key_exists('user_id', $arrays) || array_key_exists('uid', $arrays)) {
            // 不允许包含user_id或者uid，防止恶意覆盖user_id外键
            throw new MissException([
                // 异常消息内容
                'message' => '参数中包含有非法的参数名user_id或者uid'
            ]);
        } */
        $newArray = [];
        foreach ($this->rule as $key => $value) {
            $newArray[$key] = $arrays[$key];
        }
        return $newArray;
    }
    /**
     * 自定义-判断是否整数-的验证规则
     * 验证方法可以传入的参数共有5个（后面三个根据情况选用），依次为：
     * @param  [type]  $value [验证数据]
     * @param  string  $rule  [验证规则]
     * @param  string  $data  [全部数据（数组）]
     * @param  string  $field [字段名]
     * @param  string  $title [字段描述]
     * 自定义的验证规则方法名不能和已有的规则冲突。
     * @return boolean        [description]
     */
    protected function isPositiveInteger($value, $rule, $data = [], $field = '', $title = '')
    {
        if (is_numeric($value) && is_int($value + 0) && ($value + 0) > 0) {
            return true;
        }
        // 可以自定义异常代码和http状态码
        // $this->code = 10000;
        // $this->httpCode = 400;
        return $field . '必须是正整数';
    }
    /**
     * 自定义-判断是否为空-的验证规则
     * 验证方法可以传入的参数共有5个（后面三个根据情况选用），依次为：
     * @param  [type]  $value [验证数据]
     * @param  string  $rule  [验证规则]
     * @param  string  $data  [全部数据（数组）]
     * @param  string  $field [字段名]
     * @param  string  $title [字段描述]
     * 自定义的验证规则方法名不能和已有的规则冲突。
     * @return boolean        [description]
     */
    protected function isNotEmpty($value, $rule, $data = [], $field = '', $title = '')
    {
        if (empty($value)) {
            return $field . '不允许为空';
        } else {
            return true;
        }
    }
    /**
     * 自定义手机号的验证规则
     * 没有使用TP的正则验证，集中在一处方便以后修改
     * 不推荐使用正则，因为复用性太差
     * 验证方法可以传入的参数共有5个（后面三个根据情况选用），依次为：
     * @param  [type]  $value [验证数据]
     * @param  string  $rule  [验证规则]
     * @param  string  $data  [全部数据（数组）]
     * @param  string  $field [字段名]
     * @param  string  $title [字段描述]
     * 自定义的验证规则方法名不能和已有的规则冲突。
     * @return boolean        [description]
     */
    protected function isMobile($value, $rule, $data = [], $field = '', $title = '')
    {
        $rule = '^1(3|4|5|7|8)[0-9]\d{8}$^';
        $result = preg_match($rule, $value);
        if ($result) {
            return true;
        } else {
            return false;
        }
    }
    // 设置错误码
    protected function username($value, $rule, $data = [], $field = '', $title = '')
    {
        $this->code = 100000;
        return true;
    }
    // 设置错误码
    protected function password($value, $rule, $data = [], $field = '', $title = '')
    {
        $this->code = 100001;
        return true;
    }
}
